package org.zhadoop.stream.cql.semanticanalyzer.parser.context;

import java.util.List;

import org.zhadoop.stream.cql.DriverContext;
import org.zhadoop.stream.cql.exception.CQLException;
import org.zhadoop.stream.cql.exception.SemanticAnalyzerException;
import org.zhadoop.stream.cql.hooks.SemanticAnalyzeHook;
import org.zhadoop.stream.cql.semanticanalyzer.SelectStatementAnalyzer;
import org.zhadoop.stream.cql.semanticanalyzer.SemanticAnalyzer;
import org.zhadoop.stream.cql.semanticanalyzer.parsecontextwalker.ParseContextWalker;
import org.zhadoop.stream.cql.tasks.LazyTask;
import org.zhadoop.stream.cql.tasks.Task;

/**
 * select 语句解析内容
 * 
 * @author zwd
 *
 */
public class SelectStatementContext extends ParseContext {

	private SelectClauseContext select;

	private FromClauseContext from;

	private WhereClauseContext where;

	private GroupbyClauseContext groupby;

	private HavingClauseContext having;

	private OrderbyClauseContext orderby;

	private LimitClauseContext limit;

	private ParallelClauseContext parallel;

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append(select.toString());
		apendFromClause(sb);
		apendWhereClause(sb);
		apendGroupbyClause(sb);
		apendHavingClause(sb);
		apendOrderbyClause(sb);
		apendLimitClause(sb);
		apendParallelClause(sb);
		return sb.toString();
	}

	private void apendParallelClause(StringBuilder sb) {
		if (parallel != null) {
			sb.append(" " + parallel.toString());
		}
	}

	private void apendWhereClause(StringBuilder sb) {
		if (where != null) {
			sb.append(" " + where.toString());
		}
	}

	private void apendGroupbyClause(StringBuilder sb) {
		if (groupby != null) {
			sb.append(" " + groupby.toString());
		}
	}

	private void apendHavingClause(StringBuilder sb) {
		if (having != null) {
			sb.append(" " + having.toString());
		}
	}

	private void apendOrderbyClause(StringBuilder sb) {
		if (orderby != null) {
			sb.append(" " + orderby.toString());
		}
	}

	private void apendLimitClause(StringBuilder sb) {
		if (limit != null) {
			sb.append(" " + limit.toString());
		}
	}

	private void apendFromClause(StringBuilder sb) {
		if (from != null) {
			sb.append(" " + from.toString());
		}
	}

	public SelectClauseContext getSelect() {
		return select;
	}

	public void setSelect(SelectClauseContext select) {
		this.select = select;
	}

	public FromClauseContext getFrom() {
		return from;
	}

	public void setFrom(FromClauseContext from) {
		this.from = from;
	}
	
	public WhereClauseContext getWhere() {
		return where;
	}

	public void setWhere(WhereClauseContext where) {
		this.where = where;
	}

	public GroupbyClauseContext getGroupby() {
		return groupby;
	}

	public void setGroupby(GroupbyClauseContext groupby) {
		this.groupby = groupby;
	}

	public HavingClauseContext getHaving() {
		return having;
	}

	public void setHaving(HavingClauseContext having) {
		this.having = having;
	}

	public OrderbyClauseContext getOrderby() {
		return orderby;
	}

	public void setOrderby(OrderbyClauseContext orderby) {
		this.orderby = orderby;
	}

	public LimitClauseContext getLimit() {
		return limit;
	}

	public void setLimit(LimitClauseContext limit) {
		this.limit = limit;
	}

	public ParallelClauseContext getParallel() {
		return parallel;
	}

	public void setParallel(ParallelClauseContext parallel) {
		this.parallel = parallel;
	}

	@Override
	public Task createTask(DriverContext driverContext, List<SemanticAnalyzeHook> analyzeHooks) throws CQLException {
		return new LazyTask();
	}

	@Override
	public SemanticAnalyzer createAnalyzer() throws SemanticAnalyzerException {
		return new SelectStatementAnalyzer(this);
	}
	@Override
	protected void walkChild(ParseContextWalker walker) {
		walkExpression(walker, select);
        walkExpression(walker, from);
        walkExpression(walker, where);
        walkExpression(walker, orderby);
        walkExpression(walker, groupby);
        walkExpression(walker, having);
        walkExpression(walker, limit);
        walkExpression(walker, parallel);
	}

}
